#include "myDialect/toyDialect.h"
#include "myDialect/toyOps.h"
#include "myDialect/toyTypes.h"

#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/TypeSupport.h"

#include "mlir/IR/Builders.h"
#include "mlir/Interfaces/FunctionImplementation.h"
#include "mlir/IR/OpImplementation.h"

#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/TypeSize.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include <optional>

using namespace mlir;
using namespace mlir::toy;


LogicalResult parseElementTypes(AsmParser &parser, SmallVector<mlir::Type> elemTypes){
    // Parse the element types of the struct.
    do {
        // Parse the current element type.
        SMLoc typeLoc = parser.getCurrentLocation();
        mlir::Type elementType;
        if (parser.parseType(elementType))
            return failure();

        // Check that the type is either a TensorType or another StructType.
        if (!elementType.isa<mlir::TensorType, toy::toyStructType>()) {
        parser.emitError(typeLoc, "element type for a struct must either "
                                    "be a TensorType or a StructType, got: ")
            << elementType;
            return failure();
        }
        elemTypes.push_back(elementType);

        // Parse the optional: `,`
    } while (succeeded(parser.parseOptionalComma()));
    return success();
}
void printElementTypes(AsmPrinter &printer, ArrayRef<mlir::Type> elemTypes) {
    llvm::interleaveComma(elemTypes, printer);
    return;
}


#define GET_TYPEDEF_CLASSES
#include "myDialect/toyTypes.cpp.inc"

void ToyDialect::registerTypes() {
    addTypes<
#define GET_TYPEDEF_LIST
#include "myDialect/toyTypes.cpp.inc"
      >();
}